package com.benchmark.springboot.config;


import com.power.common.net.SSLSocketFactoryBuilder;
import com.power.common.net.TrustAnyTrustManager;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

import javax.annotation.Resource;
import java.net.Proxy;
import java.util.concurrent.TimeUnit;

/**
 * @author yu 2019/8/5.
 */
@Configuration
public class OkHttpConfiguration {

    private static final Logger LOGGER = LoggerFactory.getLogger(OkHttpConfiguration.class);

    @Resource
    private ConnectionPool connectionPool;

    @Resource
    private Environment environment;

    @Resource
    private Proxy proxy;

    /**
     * 创建httpclient
     *
     * @return
     */
    @Bean
    @ConditionalOnMissingBean(name = "okHttpClient")
    public OkHttpClient okHttpClient() {
        return createHttpClient(this.connectionPool, null, environment);
    }

    /**
     * 代理模式的OHttpClient
     *
     * @return
     */
    @Bean(name = "proxyOkHttpClient")
    @ConditionalOnMissingBean(name = "proxyOkHttpClient")
    public OkHttpClient proxyOkHttpClient() {
        boolean usedProxy = Boolean.valueOf(environment.getProperty("http.proxy.enable", "true"));
        if (usedProxy) {
            return createHttpClient(connectionPool, proxy, environment);
        }
        return createHttpClient(this.connectionPool, null, environment);
    }

    /**
     * 创建OkHttpClient
     *
     * @param connectionPool 连接池
     * @param proxy          代理对象
     * @param environment
     * @return
     */
    private OkHttpClient createHttpClient(ConnectionPool connectionPool, Proxy proxy, Environment environment) {
        int connectTimeout = NumberUtils.toInt(environment.getProperty("restTemplate.connectTimeout"), 1000);
        int readTimeout = NumberUtils.toInt(environment.getProperty("restTemplate.readTimeout"), 1000);
        int writeTimeout = NumberUtils.toInt(environment.getProperty("restTemplate.writeTimeout"), 1000);
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.sslSocketFactory(SSLSocketFactoryBuilder.getSslSocketFactory(), new TrustAnyTrustManager())
                .retryOnConnectionFailure(false)
                .connectionPool(connectionPool)
                .hostnameVerifier((s, sslSession) -> true)
                .connectTimeout(connectTimeout, TimeUnit.SECONDS)
                .readTimeout(readTimeout, TimeUnit.SECONDS)
                .writeTimeout(writeTimeout, TimeUnit.SECONDS);
        if (proxy != null) {
            LOGGER.debug("building proxy for REST connection -> address is {}", proxy.address().toString());
            builder.proxy(proxy);
        }
        return builder.build();
    }
}
